#include "HttpClientExample.h"
#include <iostream>

HttpClientExample::HttpClientExample()
{
    _syncHttpClient = new WSyncHttpClient();
    _asyncHttpClient = new WAsyncHttpClient();
}

HttpClientExample::~HttpClientExample()
{
    delete _syncHttpClient;
    delete _asyncHttpClient;
}

void HttpClientExample::testSyncRequest(const std::string &url, const HttpClientReqMsg &reqMsg)
{
    std::shared_ptr<HttpClientRspMsg> rspMsg = _syncHttpClient->sendRequest(url, reqMsg, 5);
    if (rspMsg->errStatus != 0)
    {
        std::cout << "HttpClientExample::testSyncRequest error status: " << rspMsg->errStatus << std::endl;
        return;
    }

    std::cout << "================print testSyncRequest result====================" << std::endl;
    std::cout << "Response Code:" << rspMsg->code << std::endl;
    std::cout << "Response Headers:" << std::endl;
    for (const auto& pair : rspMsg->headers) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }
    std::cout << "Response Body:" << std::endl << rspMsg->body << std::endl;
    std::cout << "================================================================" << std::endl;
}

void HttpClientExample::testSyncDownloadFile(std::string url, const HttpClientReqMsg &reqMsg)
{
    _fileId++;
    HttpClientCbFun cbFun = std::bind(&HttpClientExample::handleSyncDownloadFileCb, this, _fileId, std::placeholders::_1);
    _syncHttpClient->sendRequestToDwFile(url, reqMsg, cbFun);
}

void HttpClientExample::testAsyncRequest(std::string url, const HttpClientReqMsg &reqMsg)
{
    HttpClientCbFun cbFun = std::bind(&HttpClientExample::handleAsyncReqCb, this, std::placeholders::_1);
    _asyncHttpClient->sendRequest(url, reqMsg, cbFun);
}

void HttpClientExample::testAsyncDownloadFile(std::string url, const HttpClientReqMsg &reqMsg)
{
    _fileId++;
    HttpClientCbFun cbFun = std::bind(&HttpClientExample::handleAsyncDownloadFileCb, this, _fileId, std::placeholders::_1);
    _asyncHttpClient->sendRequestToDwFile(url, reqMsg, cbFun);
}

void HttpClientExample::run()
{
    _asyncHttpClient->run();
}

void HttpClientExample::handleAsyncReqCb(std::shared_ptr<HttpClientRspMsg> &rspMsg)
{
    if (rspMsg->errStatus != 0)
    {
        std::cout << "HttpClientExample::handleAsyncReqCb error status: " << rspMsg->errStatus << std::endl;
        return;
    }

    std::cout << "================print handleAsyncReqCb result====================" << std::endl;
    std::cout << "Response Code:" << rspMsg->code << std::endl;
    std::cout << "Response Headers:" << std::endl;
    for (const auto& pair : rspMsg->headers) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }
    std::cout << "Response Body:" << std::endl << rspMsg->body << std::endl << std::endl;
    std::cout << "================================================================" << std::endl;
}

void HttpClientExample::handleAsyncDownloadFileCb(int64_t fileId, std::shared_ptr<HttpClientRspMsg> &rspMsg)
{
    if (rspMsg->errStatus != 0)
    {
        std::cout << "HttpClientExample::handleAsyncDownloadFileCb error status: " << rspMsg->errStatus << std::endl;
        if (_fileIdMap.find(fileId) != _fileIdMap.end())
        {
            fclose(_fileIdMap[fileId]);
        }
        _fileIdMap.erase(fileId);
        return;
    }

    if (_fileIdMap.find(fileId) == _fileIdMap.end())
    {
        FILE* file = fopen("async.mp4", "w");
        _fileIdMap[fileId] = file;
        std::cout << "HttpClientExample::handleAsyncDownloadFileCb header: " << std::endl;
        for (const auto& pair : rspMsg->headers) {
            std::cout << pair.first << ": " << pair.second << std::endl;
        }
    }

    fwrite(rspMsg->chunk->c_str(), 1, rspMsg->chunk->size(), _fileIdMap[fileId]);

    if (rspMsg->finishRecvChunk)
    {
        fclose(_fileIdMap[fileId]);
        _fileIdMap.erase(fileId);
        std::cout << "HttpClientExample::handleAsyncDownloadFileCb download file success" << std::endl;
    }
}

void HttpClientExample::handleSyncDownloadFileCb(int64_t fileId, std::shared_ptr<HttpClientRspMsg> &rspMsg)
{
    if (rspMsg->errStatus != 0)
    {
        std::cout << "HttpClientExample::handleSyncDownloadFileCb error status: " << rspMsg->errStatus << std::endl;
        if (_fileIdMap.find(fileId) != _fileIdMap.end())
        {
            fclose(_fileIdMap[fileId]);
        }
        _fileIdMap.erase(fileId);
        return;
    }

    if (_fileIdMap.find(fileId) == _fileIdMap.end())
    {
        FILE* file = fopen("sync.mp4", "w");
        _fileIdMap[fileId] = file;
        std::cout << "HttpClientExample::handleSyncDownloadFileCb header: " << std::endl;
        for (const auto& pair : rspMsg->headers) {
            std::cout << pair.first << ": " << pair.second << std::endl;
        }
    }

    fwrite(rspMsg->chunk->c_str(), 1, rspMsg->chunk->size(), _fileIdMap[fileId]);

    if (rspMsg->finishRecvChunk)
    {
        fclose(_fileIdMap[fileId]);
        _fileIdMap.erase(fileId);
        std::cout << "HttpClientExample::handleSyncDownloadFileCb download file success" << std::endl;
    }
}
